<template>
  <div class="test-case-container">
    <!-- 页面顶部区域 -->
    <div class="page-header">
      <div class="header-left">
        <div class="action-container">
        <div class="panel-header">
          <div class="panel-subtitle">共 <span class="highlight">{{ pages.count || 0 }}</span> 条数据</div>
        </div>
        <div class="panel-tools">
          <div class="search-box">
            <el-input
              v-model="filterText"
              placeholder="搜索用例名称"
              clearable
              class="glow-input">
              <template #append>
                <el-button @click="searchClick" class="neon-btn-primary">
                  <span>查询</span>
                </el-button>
              </template>
            </el-input>
          </div>
          <div class="filter-group">
            <el-switch
              v-model="checked"
              class="creator-switch"
              active-text="仅看我创建"
              inactive-text="全部用例"
              size="large"
              @change="creatorCase"
              style="--el-switch-on-color: #13ce66; --el-switch-off-color: #409eff"
              inline-prompt>
            </el-switch>
          </div>
          <div class="actions">
            <el-button @click="clickAdd" class="neon-btn-add" type="primary">
              <el-icon><Plus /></el-icon>新增用例
      </el-button>
    </div>
        </div>
    </div>
      </div>
      <div class="header-right">
        <div class="env-badge" v-if="envId">
          <div class="env-icon">
            <el-icon><Connection /></el-icon>
          </div>
          <div class="env-info">
            <div class="env-label">当前环境</div>
            <div class="env-name">{{ currentEnv ? currentEnv.name : '未知环境' }}</div>
          </div>
        </div>
        <div class="env-badge" v-else>
          <div class="env-icon warning">
            <el-icon><Warning /></el-icon>
          </div>
          <div class="env-info">
            <div class="env-label">环境未设置</div>
            <div class="env-name error">请选择环境</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 表格区域 -->
    <div class="main-content">
      <div class="glass-panel data-panel">
        <el-scrollbar height="calc(100vh - 300px)">
          <div class="table-container">
            <el-table 
              :data="caseList" 
              style="width: 100%"
              empty-text="暂无数据"
              row-class-name="case-row"
              :row-style="{cursor: 'pointer'}"
              :header-cell-class-name="'table-header'"
              :cell-class-name="cellClassName"
              @row-click="handleRowClick">
              
              <el-table-column align="center" type="index" width="80">
                <template #header>
                  <div class="column-header">
                    <span>序号</span>
                  </div>
                </template>
              <template #default="scope">
                  <div class="case-index">
                <span>{{ scope.$index + 1 }}</span>
                  </div>
              </template>
            </el-table-column>
              
              <el-table-column label="用例名称" min-width="220" show-overflow-tooltip class-name="case-name-column">
                <template #header>
                  <div class="column-name-header">
                    <el-icon><Document /></el-icon>
                    <span>用例名称</span>
                  </div>
                </template>
              <template #default="scope">
                  <div class="case-name">
                    <div class="case-icon" :style="{
                      background: getCaseIconColor(scope.row.stepCount)
                    }">
                      <el-icon v-if="scope.row.stepCount > 0"><Document /></el-icon>
                      <el-icon v-else><Warning /></el-icon>
                    </div>
                    <span>{{ scope.row.name }}</span>
                  </div>
              </template>
            </el-table-column>
              
              <el-table-column align="center" label="所属项目" width="180" show-overflow-tooltip>
                <template #header>
                  <div class="column-header">
                    <el-icon><Folder /></el-icon>
                    <span>所属项目</span>
                  </div>
                </template>
              <template #default="scope">
                  <div class="project-name">
                    <el-tag size="small" effect="plain">{{ scope.row.project?.name || '-' }}</el-tag>
                  </div>
                </template>
              </el-table-column>
              
              <el-table-column label="步骤" width="120" align="center">
                <template #header>
                  <div class="column-header">
                    <el-icon><List /></el-icon>
                    <span>步骤</span>
                  </div>
                </template>
                <template #default="scope">
                  <div class="step-indicator">
                    <svg viewBox="0 0 36 36" class="circular-chart" :class="getStepClass(scope.row.stepCount)">
                      <path class="circle-bg"
                        d="M18 2.0845
                        a 15.9155 15.9155 0 0 1 0 31.831
                        a 15.9155 15.9155 0 0 1 0 -31.831"
                      />
                      <path class="circle"
                        stroke-dasharray="30, 100"
                        :stroke-dasharray="`${getStepPercentage(scope.row.stepCount)}, 100`"
                        d="M18 2.0845
                        a 15.9155 15.9155 0 0 1 0 31.831
                        a 15.9155 15.9155 0 0 1 0 -31.831"
                      />
                      <text x="18" y="21.35" class="percentage">{{ scope.row.stepCount }}</text>
                    </svg>
                  </div>
                </template>
              </el-table-column>
              
              <el-table-column label="用例描述" align="center" min-width="250" show-overflow-tooltip>
                <template #header>
                  <div class="column-header">
                    <el-icon><ChatDotRound /></el-icon>
                    <span>用例描述</span>
                  </div>
                </template>
                <template #default="scope">
                  <div class="description">
                    <el-tooltip 
                      effect="dark" 
                      :content="scope.row.desc || '暂无描述'" 
                      placement="top" 
                      :disabled="!scope.row.desc || scope.row.desc.length <= 20">
                      <span>{{ scope.row.desc || '暂无描述' }}</span>
              </el-tooltip>
                  </div>
              </template>
            </el-table-column>
              
              <el-table-column label="创建信息" width="220" align="center">
                <template #header>
                  <div class="column-header">
                    <el-icon><UserFilled /></el-icon>
                    <span>创建信息</span>
                  </div>
                </template>
              <template #default="scope">
                  <div class="user-info">
                    <div class="avatar" :class="{'self-avatar': scope.row.creator === username}">
                      {{ getAvatarText(scope.row.creator) }}
                    </div>
                    <div class="info-detail">
                      <div class="username" :class="{'self-name': scope.row.creator === username}">
                        {{ scope.row.creator || '未知' }}
                      </div>
                      <div class="time">{{ formatTime(scope.row.create_time) }}</div>
                    </div>
                  </div>
              </template>
            </el-table-column>
              
              <el-table-column label="最后更新" width="220" align="center">
                <template #header>
                  <div class="column-header">
                    <el-icon><Edit /></el-icon>
                    <span>最后更新</span>
                  </div>
                </template>
              <template #default="scope">
                  <div class="user-info" v-if="scope.row.update_time">
                    <div class="avatar">
                      {{ getAvatarText(scope.row.modifier) }}
                    </div>
                    <div class="info-detail">
                      <div class="username">
                        {{ scope.row.modifier || '未知' }}
                      </div>
                      <div class="time">{{ formatTime(scope.row.update_time) }}</div>
                    </div>
                  </div>
                  <div class="no-update" v-else>尚未更新</div>
              </template>
            </el-table-column>
              
              <el-table-column label="操作" fixed="right" width="200" align="center">
                <template #header>
                  <div class="column-header">
                    <el-icon><Operation /></el-icon>
                    <span>操作</span>
                  </div>
                </template>
              <template #default="scope">
                  <div class="actions-group">
                    <el-tooltip content="运行用例" placement="top">
                      <el-button 
                        @click.stop="runCase(scope.row)" 
                        circle 
                        :class="['action-btn', 'run-btn', {'disabled': scope.row.stepCount <= 0}]"
                        :disabled="scope.row.stepCount <= 0"
                        type="success">
                        <el-icon><VideoPlay /></el-icon>
                      </el-button>
                    </el-tooltip>
                    <el-tooltip content="管理步骤" placement="top">
                      <el-button 
                        @click.stop="clickEdit(scope.row)" 
                        circle 
                        class="action-btn edit-btn"
                        type="primary">
                        <el-icon><SetUp /></el-icon>
                      </el-button>
                    </el-tooltip>
                    <el-tooltip content="删除用例" placement="top">
                      <el-button 
                        @click.stop 
                        circle 
                        class="action-btn delete-btn"
                        type="danger">
                        <el-popconfirm
                          title="确定要删除此用例吗？"
                          confirm-button-text="确定"
                          cancel-button-text="取消"
                          @confirm="delCase(scope.row.id)">
                          <template #reference>
                            <el-icon><Delete /></el-icon>
                          </template>
                        </el-popconfirm>
                      </el-button>
                    </el-tooltip>
                  </div>
              </template>
            </el-table-column>
    </el-table>
    </div>

          <!-- 分页器 -->
    <div class="pagination-container">
      <el-pagination  background layout="total, prev, pager, next, jumper"
                    @current-change="currentPages"
                    :default-page-size="100"
                    :total="pages.count"
                    :current-page="pages.current"
                   next-text="下一页" prev-text="上一页">
      </el-pagination>
    </div>
    </el-scrollbar>
      </div>
  </div>

    <!-- 新增用例弹窗 -->
    <el-dialog 
      v-model="addDlg" 
      custom-class="custom-dialog"
      width="550px" 
      destroy-on-close
      :show-close="false"
      :close-on-click-modal="false">
      <template #header>
        <div class="dialog-header">
          <h3 class="dialog-title">创建新测试用例</h3>
        </div>
      </template>
      <div class="dialog-content">
        <el-form 
          :model="addForm"  
          :rules="rulesCase" 
          ref="CaseRef" 
          label-position="top" 
          class="case-form">
          <el-form-item label="用例名称" prop="name">
            <el-input 
              v-model="addForm.name" 
              placeholder="输入用例名称"
              maxlength="50"
              show-word-limit
              class="form-input"/>
      </el-form-item>
          <el-form-item label="所属项目" prop="project_id">
            <el-input 
              v-model="addForm.project_id" 
              class="form-input" 
              disabled>
            </el-input>
      </el-form-item>
			<el-form-item label="用例描述" prop="desc">
            <el-input 
              type="textarea" 
              v-model="addForm.desc" 
              placeholder="输入用例描述"
              rows="4"
              maxlength="200"
              show-word-limit
              class="form-input"/>
      </el-form-item>
		</el-form>
      </div>
		<template #footer>
        <div class="dialog-footer">
          <el-button @click="clearValidation" class="cancel-btn">
            取消
          </el-button>
          <el-button type="primary" @click="addCase" :loading="submitting" class="confirm-btn">
            确认创建
          </el-button>
        </div>
		</template>
	</el-dialog>

  <!-- 显示运行结果 -->
  <el-drawer v-model="ResultDlg" :with-header="false" size="50%">
		<div style="padding:20px;">
			<el-descriptions title="执行结果" border :column="4" style="text-align: center;">
				<el-descriptions-item label="总数" ><b style="color: #00aaff">{{ runScentResult.all }}</b></el-descriptions-item>
				<el-descriptions-item label="通过"><b style="color: #00aa7f">{{ runScentResult.success }}</b></el-descriptions-item>
				<el-descriptions-item label="失败"><b style="color: orangered">{{ runScentResult.fail }}</b></el-descriptions-item>
				<el-descriptions-item label="错误"><b style="color: #fca130">{{ runScentResult.error }}</b></el-descriptions-item>
			</el-descriptions>
			<div style="height: 40px;line-height: 40px;"><b>执行详情</b></div>
			<el-scrollbar height="calc(100vh - 180px)">
				<el-table :data="runScentResult.cases" style="width: 100%" empty-text="暂无数据">
					<el-table-column type="expand">
						<template #default="props">
							<caseResult :result="props.row"></caseResult>
						</template>
					</el-table-column>
					<el-table-column label="步骤名" prop="name" />
					<el-table-column label="请求方法" prop="method">
            <template #default="props">
               <span v-if="props.row.type === 'api'">{{ props.row.method }}</span>
						</template>
          </el-table-column>
					<el-table-column label="响应状态码" prop="status_cede">
            <template #default="props">
               <span v-if="props.row.type === 'api'">{{ props.row.status_cede }}</span>
						</template>
          </el-table-column>
					<el-table-column label="执行结果" prop="state" min-width="40px">
						<template #default="props">
							<span v-if="props.row.state == '成功'" style="color: #00AA7F;">{{ props.row.state }}</span>
              <span v-else-if="props.row.state == '错误'" style="color: #fca130;">{{ props.row.state }}</span>
							<span v-else style="color:#F56C6C">{{ props.row.state }}</span>
						</template>
					</el-table-column>
				</el-table>
			</el-scrollbar>
		</div>
	</el-drawer>
  </div>
</template>

<script>
import { mapMutations, mapState } from "vuex";
import caseResult from '../../components/common/caseResult.vue';
import { ElMessage, ElNotification, ElMessageBox, ElLoading } from "element-plus";
import * as echarts from 'echarts/core';
import { PieChart } from 'echarts/charts';
import { LabelLayout } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import { 
  Plus, View, Search, VideoPlay, Management, Document, Delete, Grid, List,
  CircleCheck, CircleClose, Warning, InfoFilled, WarningFilled, Close, Check,
  User, Monitor, Connection, Collection, Operation, ChatDotRound, Avatar, Edit,
  SetUp, DataAnalysis, Folder, Histogram, PieChart as PieChartIcon, Opportunity,
  Refresh, UserFilled
} from '@element-plus/icons-vue';

echarts.use([PieChart, LabelLayout, CanvasRenderer]);

export default {
  computed: {
    ...mapState(['pro', 'envId', 'testEnvs']),
    username() {
			return window.sessionStorage.getItem('username');
		},
   currentEnv() {
    if (!this.envId || !this.testEnvs || this.testEnvs.length === 0) return null;
    return this.testEnvs.find(env => env.id === this.envId) || this.testEnvs[0];
  },
  },
  components: {
    caseResult,
    Plus, View, Search, VideoPlay, Management, Document, Delete, Grid, List,
    CircleCheck, CircleClose, Warning, InfoFilled, WarningFilled, Close, Check,
    User, Monitor, Connection, Collection, Operation, ChatDotRound, Avatar, Edit,
    SetUp, DataAnalysis, Folder, Histogram, PieChartIcon, Opportunity, Refresh,
    UserFilled
  },
  data() {
    return {
      filterText: '',
      pages: {},
      caseList: [],
      ResultDlg: false,
      runScentResult: {},
      addDlg: false,
      checked: false,
      submitting: false,
      pageSize: 10,
      chart: null,
      iconColors: [
        'linear-gradient(135deg, #1890ff, #2979ff)',
        'linear-gradient(135deg, #38b6ff, #59c1ff)',
        'linear-gradient(135deg, #0080ff, #42a5f5)',
        'linear-gradient(135deg, #2196f3, #1976d2)',
        'linear-gradient(135deg, #3f51b5, #303f9f)'
      ],
      rulesCase: {
				name: [
					{
						required: true,
						message: '请输入用例名称',
						trigger: 'blur'
					}
				],
				project_id: [
					{
						required: true,
						message: '请选择项目',
						trigger: 'blur'
					}
				],
			},
      addForm: {
        name: '',
        project_id: '',
        desc: '',
        creator: '',
        stepCount: 0,
      },
      colorMap: {}, // 用于存储用户头像的颜色
      loadingConfig: {
        spinner: 'Loading', // 修改为Element Plus图标组件名称
      }
    }
  },
 methods: {
    ...mapMutations(['CaseInfo']),
    
    // 设置表格单元格样式
    cellClassName({row, column, rowIndex, columnIndex}) {
      if (column.label === '步骤' && row.stepCount <= 0) {
        return 'empty-steps-cell';
      }
      return '';
    },

    
    // 获取用例图标颜色
    getCaseIconColor(stepCount) {
      if (stepCount <= 0) {
        return 'linear-gradient(135deg, #f5a623, #f27121)';
      }
      const index = (stepCount * 7) % this.iconColors.length;
      return this.iconColors[index];
    },
    
    // 获取步骤环形图样式类
    getStepClass(count) {
      if (count <= 0) return 'empty-chart';
      if (count < 3) return 'low-chart';
      if (count < 10) return 'medium-chart';
      return 'high-chart';
    },
    
    // 获取状态码样式类型
    getStatusBadgeType(code) {
      if (!code) return '';
      code = parseInt(code);
      if (code >= 200 && code < 300) return 'success';
      if (code >= 300 && code < 400) return 'info';
      if (code >= 400 && code < 500) return 'warning';
      if (code >= 500) return 'danger';
      return '';
    },
    
    // 表格行样式
    tableRowClassName({row, rowIndex}) {
      if (row.stepCount <= 0) {
        return 'empty-steps-row';
      }
      return rowIndex % 2 === 0 ? 'even-row' : 'odd-row';
    },
    
    // 行点击事件
    handleRowClick(row) {
      this.clickEdit(row);
    },
    
    // 获取步骤百分比 (用于环形进度条)
    getStepPercentage(count) {
      if (!count || count <= 0) return 0;
      return Math.min(count * 10, 100); // 每10个步骤为100%
    },
    
    // 获取结果状态类名
    getResultClassName(state) {
      if (state === '成功') return 'result-success';
      if (state === '错误') return 'result-warning';
      return 'result-error';
    },
    
    // 获取步骤颜色
    getStepColor(count) {
      if (!count || count <= 0) return '#909399';
      if (count < 3) return '#E6A23C'; // 少于3个步骤黄色
      if (count < 10) return '#409EFF'; // 少于10个步骤蓝色
      return '#67C23A'; // 超过10个步骤绿色
    },
    
    // 获取头像颜色
    getAvatarColor(username) {
      if (!username) return '#909399';
      if (!this.colorMap[username]) {
        // 生成一个随机但固定的颜色
        const colors = [
          '#f56c6c', '#e6a23c', '#409eff', '#67c23a', '#909399',
          '#8a2be2', '#00bcd4', '#ff9800', '#9c27b0', '#2196f3'
        ];
        const index = username.charCodeAt(0) % colors.length;
        this.colorMap[username] = colors[index];
      }
      return this.colorMap[username];
    },
    
    // 获取头像文本
    getAvatarText(username) {
      if (!username) return '?';
      return username.substring(0, 1).toUpperCase();
    },
    
    // 格式化时间
    formatTime(timestamp) {
      if (!timestamp) return '未知时间';
      return this.$tools.rTime(timestamp);
    },
    
    // 获取请求方法类型
    getMethodType(method) {
      if (!method) return '';
      method = method.toUpperCase();
      switch (method) {
        case 'GET': return 'success';
        case 'POST': return 'primary';
        case 'PUT': return 'warning';
        case 'DELETE': return 'danger';
        case 'PATCH': return 'info';
        default: return '';
      }
    },
    
    // 获取状态码类型
    getStatusType(code) {
      if (!code) return '';
      code = parseInt(code);
      if (code >= 200 && code < 300) return 'success';
      if (code >= 300 && code < 400) return 'info';
      if (code >= 400 && code < 500) return 'warning';
      if (code >= 500) return 'danger';
      return '';
    },
    
    // 获取成功率
    getSuccessRate() {
      if (!this.runScentResult.all || this.runScentResult.all <= 0) return 0;
      return Math.round((this.runScentResult.success / this.runScentResult.all) * 100);
    },
    
    // 获取失败率
    getFailRate() {
      if (!this.runScentResult.all || this.runScentResult.all <= 0) return 0;
      return Math.round((this.runScentResult.fail / this.runScentResult.all) * 100);
    },
    
    // 获取错误率
    getErrorRate() {
      if (!this.runScentResult.all || this.runScentResult.all <= 0) return 0;
      return Math.round((this.runScentResult.error / this.runScentResult.all) * 100);
    },
    
    // 初始化图表
    initChart() {
      if (!this.ResultDlg || !this.runScentResult.all) return;
      
      this.$nextTick(() => {
        if (this.$refs.chartContainer) {
          if (this.chart) {
            this.chart.dispose();
          }
          
          this.chart = echarts.init(this.$refs.chartContainer);
          
          // 主题色和渐变
          const successColor = {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [{
              offset: 0,
              color: '#67C23A'
            }, {
              offset: 1,
              color: '#4caf50'
            }]
          };
          
          const failColor = {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 1,
            y2: 1,
            colorStops: [{
              offset: 0,
              color: '#F56C6C'
            }, {
              offset: 1,
              color: '#E53935'
            }]
          };
          
          const errorColor = {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 1,
            y2: 0,
            colorStops: [{
              offset: 0,
              color: '#E6A23C'
            }, {
              offset: 1,
              color: '#FFA000'
            }]
          };
          
          const option = {
            backgroundColor: 'transparent',
            tooltip: {
              trigger: 'item',
              formatter: '{b}: {c} ({d}%)',
              backgroundColor: 'rgba(30, 30, 45, 0.7)',
              borderColor: 'rgba(80, 80, 180, 0.5)',
              textStyle: {
                color: '#fff'
              }
            },
            legend: {
              orient: 'vertical',
              right: 10,
              top: 'center',
              textStyle: {
                color: '#e0e0e0'
              },
              itemWidth: 14,
              itemHeight: 14,
              itemGap: 20,
              icon: 'circle'
            },
            series: [
              {
                name: '执行结果',
                type: 'pie',
                radius: ['40%', '70%'],
                avoidLabelOverlap: false,
                itemStyle: {
                  borderRadius: 10,
                  borderColor: 'rgba(30, 30, 45, 0.8)',
                  borderWidth: 2
                },
                label: {
                  show: false
                },
                emphasis: {
                  label: {
                    show: true,
                    fontSize: '18',
                    fontWeight: 'bold',
                    color: '#ffffff'
                  },
                  scaleSize: 15
                },
                labelLine: {
                  show: false
                },
                data: [
                  { 
                    value: this.runScentResult.success || 0, 
                    name: '通过', 
                    itemStyle: { color: successColor } 
                  },
                  { 
                    value: this.runScentResult.fail || 0, 
                    name: '失败', 
                    itemStyle: { color: failColor } 
                  },
                  { 
                    value: this.runScentResult.error || 0, 
                    name: '错误', 
                    itemStyle: { color: errorColor } 
                  }
                ],
                animationType: 'scale',
                animationEasing: 'elasticOut',
                animationDelay: function (idx) {
                  return Math.random() * 200;
                }
              }
            ]
          };
          
          this.chart.setOption(option);
          window.addEventListener('resize', this.resizeChart);
        }
      });
    },
    
    // 调整图表大小
    resizeChart() {
      if (this.chart) {
        this.chart.resize();
      }
    },
    
    // 查询
   searchClick() {
      this.allTestCase(this.pro.id, this.pages.current, this.filterText);
   },

   // 点击编辑用例
    clickEdit(row) {
   this.$router.push({ name: 'TestCaseDetail' });
      this.CaseInfo(row);
   },

   // 点击新增用例
   clickAdd() {
      this.addForm.project_id = this.pro.name;
      this.addDlg = true;
    },
    
    // 添加用例
    async addCase() {
      this.$refs.CaseRef.validate(async valid => {
        if (!valid) return;
        
        this.submitting = true;
        try {
          const params = {...this.addForm};
          params.creator = this.username;
          params.project_id = this.pro.id;
          
    const response = await this.$api.createTestCase(params);
      if (response.status === 201) {
            ElNotification({
              title: '创建成功',
              message: '测试用例已成功创建',
          type: 'success',
              duration: 2000
        });
        this.addDlg = false;
            this.allTestCase(this.pro.id);
          }
        } catch (error) {
          ElMessage({
            type: 'error',
            message: '创建失败：' + (error.message || '未知错误'),
            duration: 3000
          });
        } finally {
          this.submitting = false;
        }
      });
    },

    // 切换只看自己创建
    creatorCase() {
       if (this.checked) {
        // 只看自己创建的逻辑
        this.allTestCase(this.pro.id, this.pages.current, this.filterText,this.username);
      } else {
        // 取消只看自己创建的逻辑
        this.allTestCase();
      }
    },
    
    // 获取用例列表
    async allTestCase(project=this.pro.id, page=this.pages.current, name, username) {
      try {
        const response = await this.$api.getTestCase(project, page, name, username);
        if (response.status === 200) {
          this.caseList = response.data.result || [];
          this.pages = response.data || {};
          this.addForm.project_id = this.pro.name;
        }
      } catch (error) {
        ElMessage({
          type: 'error',
          message: '获取用例列表失败: ' + (error.message || '未知错误'),
          duration: 3000
        });
      } finally {
      }
    },

    // 页码变化
   currentPages(currentPage) {
      this.allTestCase(this.pro.id, currentPage, this.filterText, this.checked ? this.username : undefined);
      this.pages.current = currentPage;
    },
    
    // 每页条数变化
    handleSizeChange(size) {
      this.pageSize = size;
      this.currentPages(1);
    },

    // 删除用例
    async delCase(id) {
      try {
        const loadingInstance = ElLoading.service({
          text: '正在删除...',
          background: 'rgba(30, 30, 45, 0.7)'
        });
        
        const response = await this.$api.delTestCase(id);
        
        loadingInstance.close();
        
        if (response.status === 204) {
          ElNotification({
            title: '删除成功',
            message: '测试用例已成功删除',
            type: 'success',
            duration: 2000
          });
          // 刷新页面
          this.allTestCase(this.pro.id, this.pages.current, this.filterText, this.checked ? this.username : undefined);
        }
      } catch (error) {
        ElMessage({
          type: 'error',
          message: '删除失败：' + (error.message || '未知错误'),
          duration: 3000
        });
      }
  },

     // 运行测试用例
  async runCase(data) {
      const stepCount = parseInt(data.stepCount);
      
      if (stepCount <= 0) {
        ElMessage({
          type: 'warning',
          message: '该用例没有步骤，请先添加步骤再运行',
          duration: 2000
        });
        return;
      }
      
      if (!this.envId) {
        ElMessageBox.alert('请先选择执行环境后再运行用例', '未选择环境', {
          confirmButtonText: '确定',
          type: 'warning'
        });
        return;
      }
      
      // 显示加载动画
      const loadingInstance = ElLoading.service({
        text: '正在执行测试用例，请稍候...',
        spinner: 'Loading',
        background: 'rgba(41, 121, 255, 0.3)'
      });
      
      try {
				const params = {
					env: this.envId,
					scene: data.id
				};
        
				const response = await this.$api.runCases(data.id, params);
				if (response.status == 200) {
          // 关闭加载动画
          loadingInstance.close();
          
					// 显示执行结果到窗口页面
          this.runScentResult = response.data || {};
					this.ResultDlg = true;
          
          // 初始化图表
          this.initChart();
          
          // 根据结果显示不同通知
          const successRate = this.getSuccessRate();
          if (successRate === 100) {
            ElNotification({
              title: '执行成功',
              message: `全部 ${this.runScentResult.all} 个步骤执行成功`,
              type: 'success',
              duration: 3000
            });
          } else if (successRate >= 80) {
            ElNotification({
              title: '部分成功',
              message: `${this.runScentResult.success}/${this.runScentResult.all} 个步骤执行成功`,
					type: 'warning',
              duration: 3000
            });
          } else {
            ElNotification({
              title: '执行失败',
              message: `仅 ${this.runScentResult.success}/${this.runScentResult.all} 个步骤执行成功`,
              type: 'error',
              duration: 3000
            });
          }
        }
      } catch (error) {
        // 关闭加载动画
        loadingInstance.close();
        
        ElMessage({
          type: 'error',
          message: '执行失败：' + (error.message || '未知错误'),
          duration: 3000
        });
      }
    },
    
    // 清除验证
  clearValidation() {
      this.addDlg = false;
      this.$refs.CaseRef?.clearValidate(); // 清除验证信息
      // 重置表单
      this.addForm = {
        name: '',
        project_id: this.pro.name,
        desc: '',
        creator: '',
        stepCount: 0,
      };
    },
 },
 created() {
  this.allTestCase(this.pro.id);
  },
  mounted() {
    // 检查环境ID
    if (!this.envId) {
      ElMessage({
        type: 'info',
        message: '请先选择执行环境以便运行测试用例',
        duration: 3000
      });
    }
  },
  beforeUnmount() {
    window.removeEventListener('resize', this.resizeChart);
    if (this.chart) {
      this.chart.dispose();
      this.chart = null;
    }
  },
  watch: {
    ResultDlg(val) {
      if (val) {
        this.initChart();
      }
    }
  }
}
</script>

<style scoped>
/* 基础样式 */
.test-case-container {
  padding: 20px;
  min-height: 100vh;
  background: #ffffff;
  color: #333333;
  position: relative;
  overflow: hidden;
}

.test-case-container::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: 
    radial-gradient(circle at 10% 20%, rgba(64, 158, 255, 0.03) 0%, transparent 25%),
    radial-gradient(circle at 80% 80%, rgba(100, 181, 246, 0.05) 0%, transparent 35%);
  pointer-events: none;
}

/* 页面头部样式 */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;

  border-bottom: 1px solid rgba(64, 158, 255, 0.2);
  position: relative;
}

.logo-container {
  display: flex;
  align-items: center;
  gap: 15px;
}

.logo-icon {
  width: 48px;
  height: 48px;
  background: linear-gradient(135deg, #1890ff, #2979ff);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  color: white;
  box-shadow: 0 0 15px rgba(41, 121, 255, 0.3);
}

.logo-icon i {
  font-size: 24px;
}

.logo-text {
  display: flex;
  flex-direction: column;
}

.text-gradient {
  font-size: 28px;
  font-weight: bold;
  background: linear-gradient(to right, #1890ff, #2979ff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  margin-bottom: 5px;
}

.env-badge {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(64, 158, 255, 0.2);
  border-radius: 10px;
  padding: 10px 15px;
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

.env-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: rgba(103, 194, 58, 0.15);
  color: #67C23A;
  font-size: 18px;
}

.env-icon i {
  font-size: 18px;
}

.env-icon.warning {
  background-color: rgba(230, 162, 60, 0.15);
  color: #E6A23C;
}

.env-info {
  display: flex;
  flex-direction: column;
}

.env-label {
  font-size: 12px;
  color: #666666;
}

.env-name {
  font-size: 14px;
  font-weight: 500;
  color: #67C23A;
}

.env-name.error {
  color: #E6A23C;
}

/* 功能区样式 */
.action-container {
  margin-bottom: 20px;
}

.glass-panel {
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(10px);
  border-radius: 12px;
  border: 1px solid rgba(64, 158, 255, 0.2);
  padding: 15px 20px;
  box-shadow: 0 8px 32px rgba(41, 121, 255, 0.05);
  position: relative;
  overflow: hidden;
}

.glass-panel::before {
  content: '';
  position: absolute;
  top: -10%;
  left: -10%;
  width: 120%;
  height: 120%;
  background: linear-gradient(45deg, transparent, rgba(64, 158, 255, 0.03), transparent);
  transform: rotate(30deg);
  pointer-events: none;
}


.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}


.panel-subtitle {
  font-size: 14px;
  color: #666666;
}

.highlight {
  color: #1890ff;
  font-weight: 600;
}

.panel-tools {
  display: flex;
  align-items: center;
  gap: 20px;
}

.search-box {
  flex: 1;
  max-width: 450px;
  margin-right: 20px;
}

.glow-input {
  width: 100%;
}

.glow-input :deep(.el-input__wrapper) {
  background-color: rgba(255, 255, 255, 0.95) !important;
  border: 1px solid rgba(64, 158, 255, 0.3) !important;
  box-shadow: none !important;
  border-radius: 8px 0 0 8px !important;
  transition: all 0.3s;
}

.glow-input:hover :deep(.el-input__wrapper) {
  border-color: rgba(64, 158, 255, 0.6) !important;
  box-shadow: 0 0 5px rgba(64, 158, 255, 0.2) !important;
}

.glow-input :deep(.el-input__inner) {
  color: #333333 !important;
}

.glow-input :deep(.el-input__prefix) {
  color: #1890ff;
}

.glow-input :deep(.el-input__prefix) i {
  font-size: 18px;
}

.glow-input :deep(.el-input-group__append) {
  padding: 0 !important;
  border: none !important;
  background-color: transparent !important;
}

.neon-btn-primary {
  background: linear-gradient(45deg, #1890ff, #2979ff) !important;
  border: none !important;
  color: white !important;
  padding: 0 20px !important;
  height: 100% !important;
  border-radius: 0 8px 8px 0 !important;
  display: flex;
  align-items: center;
  gap: 5px;
  box-shadow: 0 0 10px rgba(41, 121, 255, 0.3);
  transition: all 0.3s;
  margin-left: -1px !important;
}

.neon-btn-primary:hover {
  box-shadow: 0 0 15px rgba(41, 121, 255, 0.5);
  transform: translateY(-1px);
}

.neon-btn-primary i {
  font-size: 16px;
  margin-right: 5px;
}

.neon-btn-add {
  background: linear-gradient(45deg, #1890ff, #2979ff) !important;
  border: none !important;
  border-radius: 8px !important;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  box-shadow: 0 0 15px rgba(41, 121, 255, 0.2);
  transition: all 0.3s;
}

.neon-btn-add:hover {
  box-shadow: 0 0 20px rgba(41, 121, 255, 0.4);
  transform: translateY(-2px);
}

.neon-btn-add i {
  font-size: 16px;
  margin-right: 5px;
}

.filter-group {
  display: flex;
  align-items: center;
  gap: 10px;
}

.creator-switch {
  --el-switch-on-color: #1890ff;
  --el-switch-off-color: #999999;
}

/* 表格区域样式 */
.main-content {
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 10px;
  padding: 15px;
  box-shadow: 0 8px 24px rgba(41, 121, 255, 0.05);
}

.table-container {
  position: relative;
}

.case-row {
  transition: all 0.3s;
}

.case-row:hover {
  background-color: rgba(230, 244, 255, 0.7) !important;
}

.table-header {
  background-color: rgba(240, 248, 255, 0.7) !important;
  color: #1890ff !important;
  font-weight: 600 !important;
  border-bottom: 2px solid rgba(64, 158, 255, 0.2) !important;
  height: 50px !important;
  text-align: center !important;
}

.column-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.column-name-header {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding-left: 10px;
}

.column-header i, .column-name-header i {
  font-size: 18px;
  color: #1890ff;
  display: flex;
  align-items: center;
}


/* 表格单元格样式 */
.case-index {
  width: 34px;
  height: 34px;
  border-radius: 17px;
  background: linear-gradient(135deg, #1890ff, #2979ff);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  margin: 0 auto;
  box-shadow: 0 4px 8px rgba(41, 121, 255, 0.15);
}

.case-name {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #333333;
  justify-content: flex-start;
}

.case-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.case-icon i {
  font-size: 18px;
}

.project-name {
  margin: 0;
}

.description {
  color: #666666;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 图表样式 */
.circular-chart {
  display: block;
  margin: 0 auto;
  max-width: 100%;
  max-height: 40px;
}

.circle-bg {
  fill: none;
  stroke: rgba(200, 200, 200, 0.3);
  stroke-width: 3;
}

.circle {
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
  transition: all 0.3s;
}

.high-chart .circle {
  stroke: #67C23A;
}

.medium-chart .circle {
  stroke: #409EFF;
}

.low-chart .circle {
  stroke: #E6A23C;
}

.empty-chart .circle {
  stroke: #909399;
}

.percentage {
  fill: #333333;
  font-size: 12px;
  text-anchor: middle;
  font-weight: bold;
}

.empty-steps-cell {
  background-color: rgba(229, 57, 53, 0.05) !important;
}

/* 用户信息 */
.user-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, #1890ff, #2979ff);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 16px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
}

.self-avatar {
  background: linear-gradient(135deg, #1890ff, #2979ff);
  box-shadow: 0 0 10px rgba(24, 144, 255, 0.3);
}

.info-detail {
  display: flex;
  flex-direction: column;
  text-align: left;
}

.username {
  font-weight: 500;
  margin-bottom: 4px;
  color: #333333;
}

.self-name {
  color: #1890ff;
  position: relative;
}

.self-name::after {
  content: '(我)';
  margin-left: 4px;
  font-size: 12px;
  color: #64b5f6;
}

.time {
  font-size: 12px;
  color: #666666;
}

.no-update {
  color: #999999;
  font-style: italic;
}

/* 操作按钮 */
.actions-group {
  display: flex;
  justify-content: center;
  gap: 10px;
}

.action-btn {
  position: relative;
  width: 36px !important;
  height: 36px !important;
  font-size: 16px !important;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
  border: none !important;
  transition: all 0.3s !important;
}

.action-btn i {
  font-size: 16px;
}

.action-btn::after {
  content: '';
  position: absolute;
  top: -2px;
  left: -2px;
  right: -2px;
  bottom: -2px;
  border-radius: 50%;
  z-index: -1;
  opacity: 0;
  transition: opacity 0.3s;
}

.action-btn:hover {
  transform: translateY(-2px);
}

.action-btn:hover::after {
  opacity: 1;
}

.run-btn {
  background: linear-gradient(135deg, #67C23A, #4caf50) !important;
}

.run-btn::after {
  background: radial-gradient(circle at 50% 50%, rgba(103, 194, 58, 0.4), transparent 70%);
}

.edit-btn {
  background: linear-gradient(135deg, #1890ff, #2979ff) !important;
}

.edit-btn::after {
  background: radial-gradient(circle at 50% 50%, rgba(24, 144, 255, 0.4), transparent 70%);
}

.delete-btn {
  background: linear-gradient(135deg, #F56C6C, #e53935) !important;
}

.delete-btn::after {
  background: radial-gradient(circle at 50% 50%, rgba(245, 108, 108, 0.4), transparent 70%);
}

.action-btn.disabled {
  background: #909399 !important;
  opacity: 0.5;
  cursor: not-allowed;
}

/* 分页器 */
.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

/* 对话框样式 */
.dialog-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

.dialog-icon {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 40px;
  height: 40px;
  background: linear-gradient(135deg, #1890ff, #2979ff);
  color: white;
  border-radius: 8px;
  box-shadow: 0 4px 10px rgba(24, 144, 255, 0.3);
}

.dialog-icon i {
  font-size: 20px;
}

.dialog-title {
  margin: 0;
  color: #1890ff;
  font-size: 20px;
}

.case-form {
  margin-top: 10px;
}

.form-input {
  width: 100%;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.cancel-btn {
  display: flex;
  align-items: center;
  gap: 6px;
}

.cancel-btn i {
  font-size: 16px;
}

.confirm-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background: linear-gradient(135deg, #1890ff, #2979ff) !important;
  border: none !important;
}

.confirm-btn i {
  font-size: 16px;
}

/* 执行结果抽屉样式 */
.drawer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.drawer-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.drawer-icon {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  background: linear-gradient(135deg, #1890ff, #2979ff);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  box-shadow: 0 4px 10px rgba(24, 144, 255, 0.3);
}

.drawer-icon i {
  font-size: 20px;
}

.drawer-info {
  display: flex;
  flex-direction: column;
}

.drawer-name {
  font-size: 18px;
  font-weight: 600;
  color: #1890ff;
}

.drawer-time {
  font-size: 12px;
  color: #666666;
}

.refresh-btn {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(24, 144, 255, 0.2);
  transition: all 0.3s;
}

.refresh-btn:hover {
  transform: rotate(180deg);
  background: rgba(255, 255, 255, 0.2);
}

.refresh-btn i {
  font-size: 18px;
  color: #1890ff;
}

/* 抽屉内容样式 */
.stats-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  padding: 20px;
}

.stats-card {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  padding: 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
  border: 1px solid rgba(24, 144, 255, 0.05);
  transition: all 0.3s;
}

.stats-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
}

.card-content {
  display: flex;
  flex-direction: column;
}

.card-title {
  font-size: 14px;
  color: #666666;
  margin-bottom: 5px;
}

.card-value {
  font-size: 24px;
  font-weight: 700;
  margin-bottom: 5px;
}

.card-desc {
  font-size: 12px;
  color: #999999;
}

.card-icon {
  width: 48px;
  height: 48px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(240, 240, 250, 0.7);
}

.card-icon i {
  font-size: 24px;
}

.total-card .card-icon {
  color: #1890ff;
}

.success-card .card-icon {
  color: #67C23A;
}

.fail-card .card-icon {
  color: #F56C6C;
}

.error-card .card-icon {
  color: #E6A23C;
}

.total-card .card-value {
  color: #1890ff;
}

.success-card .card-value {
  color: #67C23A;
}

.fail-card .card-value {
  color: #F56C6C;
}

.error-card .card-value {
  color: #E6A23C;
}

/* 结果仪表盘 */
.result-dashboard {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 20px;
  padding: 0 20px 20px;
}

.chart-area {
  background: white;
  border-radius: 12px;
  padding: 15px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
}

.chart-header {
  font-size: 16px;
  font-weight: 600;
  color: #1890ff;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(24, 144, 255, 0.1);
}

.chart-container {
  flex: 1;
  min-height: 250px;
}

.detail-area {
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
}

.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  border-bottom: 1px solid rgba(24, 144, 255, 0.1);
}

.detail-title {
  font-size: 16px;
  font-weight: 600;
  color: #1890ff;
}

.detail-summary {
  display: flex;
  gap: 10px;
}


.detail-table {
  width: 100%;
}

.expand-content {
  padding: 15px;
}

.type-tag {
  font-weight: 500;
}

.result-tag {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
}

.result-tag i {
  font-size: 14px;
}

.result-success {
  color: #67C23A;
  background: rgba(103, 194, 58, 0.1);
  border: 1px solid rgba(103, 194, 58, 0.2);
}

.result-warning {
  color: #E6A23C;
  background: rgba(230, 162, 60, 0.1);
  border: 1px solid rgba(230, 162, 60, 0.2);
}

.result-error {
  color: #F56C6C;
  background: rgba(245, 108, 108, 0.1);
  border: 1px solid rgba(245, 108, 108, 0.2);
}

/* 自定义对话框和抽屉类 */
.custom-dialog {
  border-radius: 15px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid rgba(24, 144, 255, 0.2);
  box-shadow: 0 15px 40px rgba(0, 0, 0, 0.1);
}

.custom-dialog :deep(.el-dialog__header) {
  padding: 20px;
  border-bottom: 1px solid rgba(24, 144, 255, 0.1);
  background: linear-gradient(90deg, rgba(240, 248, 255, 0.9), rgba(236, 246, 255, 0.9));
}

.custom-dialog :deep(.el-dialog__body) {
  padding: 20px;
  background: white;
}

.custom-dialog :deep(.el-dialog__footer) {
  padding: 15px 20px;
  border-top: 1px solid rgba(24, 144, 255, 0.1);
  background: rgba(240, 248, 255, 0.5);
}

.result-drawer :deep(.el-drawer__header) {
  margin-bottom: 0;
  padding: 20px;
  border-bottom: 1px solid rgba(24, 144, 255, 0.1);
  background: linear-gradient(90deg, rgba(240, 248, 255, 0.95), rgba(236, 246, 255, 0.95));
}

.result-drawer :deep(.el-drawer__body) {
  padding: 0;
  background: white;
}

/* 表格悬停效果 */
.el-table__row:hover {
  background-color: rgba(230, 244, 255, 0.7) !important;
}

/* 斑马纹效果 */
.el-table__row--striped td {
  background-color: rgba(248, 250, 252, 0.7) !important;
}

.el-table {
  background-color: transparent !important;
  border-radius: 8px !important;
  overflow: hidden !important;
}

.el-table::before {
  display: none !important;
}

/* 表格边框 */
.el-table td.el-table__cell, 
.el-table th.el-table__cell {
  border-bottom: 1px solid rgba(64, 158, 255, 0.1) !important;
}

.el-table .cell {
  text-align: center !important;
}

.el-table .case-name-column .cell {
  text-align: left !important;
}
</style>
